import $fetch from '@system.fetch'
import $utils from './utils'
import { baseUrl, pkgChannel, appSource } from './config'
import { setGlobalData, getGlobalData } from '../global'
import device from '@system.device'
import router from '@system.router'
import md5 from 'crypto-js/md5'

const TIMEOUT = 10000

Promise.prototype.finally = function(callback) {
  const P = this.constructor
  return this.then(
    value => P.resolve(callback()).then(() => value),
    reason =>
      P.resolve(callback()).then(() => {
        throw reason
      })
  )
}

/**
 * 调用快应用 fetch 接口做网络请求
 * @param params
 */
function fetchPromise(params) {
  let token = getGlobalData('token')
  const { url, method, data, headers } = params
  const timestamp = Number(new Date())
  const appId = 'quick-app'
  const appSecret = '4W5GV2zVd4mM'
  const secret = `${timestamp}&${appId}&${appSecret}`
  const secretMd5 = md5(secret).toString()
  return new Promise((resolve, reject) => {
    $fetch
      .fetch({
        url,
        method,
        data,
        ...(headers && headers.tag == 'direct' ? { responseType: 'text' } : {}),
        header: {
          'x-ca-app-id': appId,
          'x-ca-timestamp': timestamp,
          'x-ca-secret': secretMd5,
          'content-type': 'application/json',
          appSource: appSource,
          // 'debug':0,
          token,
          ...headers
        }
      })
      .then(response => {
        //ad 无返回结果
        if (headers && headers.tag == 'ad') resolve()

        if (headers && headers.tag == 'direct') {
          resolve(response.data.data)
          return
        }
        //正常返回
        const result = response.data
        const content = JSON.parse(result.data)
        if (content && content.code == 201) {
          setGlobalData('token', '')
        }
        resolve(content)
      })
      .catch((error, code) => {
        if (!headers.tag || headers.tag != 'ad') {
          console.log(`--- request fail, code = ${code}, url=${url}`)
        }
        reject(error)
      })
  })
}

/**
 * 处理网络请求，timeout 是网络请求超时之后返回，默认 20s 可自行修改
 * @param params
 */
function requestHandle(params, timeout = TIMEOUT) {
  try {
    return Promise.race([
      fetchPromise(params),
      new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error('网络状况不太好，再刷新一次？'))
        }, timeout)
      })
    ])
  } catch (error) {
    console.error(error)
  }
}
/**
 * 需要授权登录
 * @param params
 */
function authentication(params) {
  let token = getGlobalData('token')
  // console.log('~~~ token:',getGlobalData('token'))
  if (!token || token == '') {
    return new Promise((resolve, reject) => {
      device.getId({
        type: ['device', 'mac', 'user', 'advertising'],
        success: ret => {
          const { device, mac, user, advertising } = ret
          // console.log('~~~ getId:','device:',device,'| mac:',mac,'| user:',user,'| advertising:',advertising)
          let data = { androidId: user }
          requestHandle({
            method: 'post',
            url: baseUrl + '/user/signup',
            data: data
          })
            .then(res => {
              if (res.code == 200) {
                const { token } = res.data
                setGlobalData('token', token)
                resolve(requestHandle(params))
              }
            })
            .catch(error => {
              console.log('~~~signup failed', error)
              reject(error)
            })
        }
      })
    })
  } else {
    return requestHandle(params)
  }
}
export default {
  post: function(url, params, headers = {}) {
    const result = {
      method: 'post',
      url: url,
      data: params,
      headers
    }
    return headers.auth === false
      ? requestHandle(result)
      : authentication(result)
  },
  get: function(url, params, headers = {}) {
    const result = {
      method: 'get',
      url: $utils.queryString(url, params),
      headers
    }
    return headers.auth === false
      ? requestHandle(result)
      : authentication(result)
  },
  put: function(url, params, headers = {}) {
    const result = {
      method: 'put',
      url: url,
      data: params,
      headers
    }
    return headers.auth === false
      ? requestHandle(result)
      : authentication(result)
  }
}
